#include <cstdio>
#include <cstring>

const int MAX_E = 2 * 1000;
const int MAX_V = 100;

struct node { int v, next, w; } E[MAX_E];
int G[MAX_V];
bool used[MAX_V];
int seq[MAX_V], col[MAX_V];
int cnt, ls, scc;
int N;

void add_edge(int i, int j, int w=1) {
	E[cnt].v = j;
	E[cnt].next = G[i];
	E[cnt].w = w;
	G[i] = cnt++;
	
	if (w > 0) add_edge(j, i, -w);
}

void dfs(int i) {
	used[i] = 1;
	for (int j=G[i]; j!=-1; j=E[j].next)
		if ((E[j].w == 1) && !used[E[j].v])
			dfs(E[j].v);
	seq[ls++] = i;
}

void dfs2(int i) {
	col[i] = scc;
	for (int j=G[i]; j!=-1; j=E[j].next)
		if (E[j].w == -1) {
			int v = E[j].v;
			if (col[v] >= 0) continue;
			dfs2(v);
		}
}

void test() {
	N = 4;
	add_edge(0, 1);
	add_edge(1, 2);
	add_edge(1, 3);
	add_edge(3, 0);
}

int main() {
	memset(G, -1, sizeof(G)); cnt = 0;
	test();

	memset(used, 0, sizeof(used));
	for (int i=0; i<N; ++i) if (!used[i]) dfs(i);

	memset(col, -1, sizeof(col));
	scc = 0;
	for (int i=ls-1; i>=0; --i) 
		if (col[seq[i]] < 0) {
			dfs2(seq[i]);
			++scc;
		}

	for (int i=0; i<N; ++i) printf("Col[%d] = %d\n", i, col[i]);
	return 0;
}	
